package com.sw.c.filter;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.sw.c.config.SystemParams;
import com.sw.c.utils.JwtTokenUtil;
import com.sw.c.utils.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.User;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public class JwtAuthorizationFilter extends BasicAuthenticationFilter {

    private final RedisUtils redisUtils;
    private final SystemParams systemParam;
    private final JwtTokenUtil jwtTokenUtil;
    private final ObjectMapper objectMapper = new ObjectMapper();

    public JwtAuthorizationFilter(AuthenticationManager authManager,
                                  JwtTokenUtil jwtTokenUtil,
                                  RedisUtils redisUtils,
                                  SystemParams systemParams) {
        super(authManager);
        this.jwtTokenUtil = jwtTokenUtil;
        this.redisUtils = redisUtils;
        this.systemParam = systemParams;
    }


    @Override
    protected void doFilterInternal(HttpServletRequest req,
                                    HttpServletResponse res,
                                    FilterChain chain) throws IOException, ServletException {

        UsernamePasswordAuthenticationToken authentication = getAuthentication(req);

        if (authentication == null) {
            log.error("您没权限访问,请登录后再尝试！");
//            redirectToLogin(res);
            return;
        }

        SecurityContextHolder.getContext().setAuthentication(authentication);
        chain.doFilter(req, res);
    }

    private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) {
        String token = request.getHeader(jwtTokenUtil.getHeader());
        if (token != null) {
            // parse the token.
            String user = jwtTokenUtil.getUsernameFromToken(token.replace("Bearer ", ""));
            if (StringUtils.isBlank(user)) {
                return null;
            }
            User obj = JSON.parseObject(user,User.class);
            boolean t = redisUtils.hasKey(systemParam.getRedisPrefix()+obj.getUsername());

            if (user != null && t) {
                return new UsernamePasswordAuthenticationToken(user, null, new ArrayList<>());
            }
        }
        return null;
    }

    private void redirectToLogin(HttpServletResponse response) throws IOException {
        Map<String, String> errorResponse = new HashMap<>();
        errorResponse.put("error", "Unauthorized");
        errorResponse.put("message", "Please log in to access this resource.");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        response.setContentType("application/json");
        objectMapper.writeValue(response.getOutputStream(), errorResponse);
    }
}
